/******************************************************
 * Graduate Project TU eTour
 * @author Hui Liu
 * @dueDate May 14, 2011
 * @purpose
 * create a new campus map overlay
 * Mark each location
 * Add name of the parking lot to the map
 * When a location is tapped
 * 	if it is a building, show its description, departments, and history
 *  if it is a shuttle stop, show next bus arriving time on this stop
 * 
 * @input
 * 
 * @output
 *
*********************************************************/
package org.TUApp.eTour;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.database.Cursor;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.view.View;
import android.view.ViewGroup.LayoutParams;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
import com.google.android.maps.Projection;

// TODO: Auto-generated Javadoc
/**
 * The Class CampusMapOverlay.
 */
public class CampusMapOverlay extends ItemizedOverlay<OverlayItem>
{
	
	/** The items. */
	private ArrayList<OverlayItem> items;
	
	/** The campus locations. */
	private  Cursor campusLocations;
	
	/** The m context. */
	private Context mContext;
	
	/** The map view. */
	private MapView mapView;
	
	/** The balloon view. */
	private BalloonOverlayView balloonView;
	
	/** The view offset. */
	private int viewOffset;
	
	/** The mc. */
	final MapController mc;
	
    /** The m text size. */
    private int mTextSize = 12;
    
    private String lType;
    
    private Drawable[] markers;

	/**
	 * Instantiates a new campus map overlay.
	 *
	 * @param defaultMarker the default marker
	 * @param cursor the cursor
	 * @param map the map
	 * @param Ltype the location type
	 */
	public CampusMapOverlay(Drawable defaultMarker, Cursor cursor, MapView map, String Ltype) {
		super(defaultMarker);
		this.mapView = map;
		lType = Ltype;
		mContext = mapView.getContext();
		viewOffset = 0;
		mc = mapView.getController();
		// set marker for different shuttle route
		if (lType.equalsIgnoreCase("S")){
		    Drawable[] markerss = {mContext.getResources().getDrawable(R.drawable.goldroute),
		    		mContext.getResources().getDrawable(R.drawable.goucher_route),
		    		mContext.getResources().getDrawable(R.drawable.k),
		    		mContext.getResources().getDrawable(R.drawable.timonium_route),
		    		mContext.getResources().getDrawable(R.drawable.rodgers_route),
		    		mContext.getResources().getDrawable(R.drawable.garage_route)};
		    markers = markerss;
		    for (Drawable marker:markers)			
		    	boundCenter(marker);
		}
//		myActivity = activity;
		boundCenterBottom(defaultMarker);
		items = new ArrayList<OverlayItem>();
	    campusLocations = cursor;
	    // add campus location data in cursor to the arraylist 
	    refreshCampusLocations();
		populate();
	}

	
	//add campus location data to the arraylist 
	/**
	 * Refresh campus locations.
	 */
	private void refreshCampusLocations() {
		//index of the item
//		int i = 0;
		//read from database
		if (campusLocations.moveToFirst())
		      do { 
			        Double lat = campusLocations.getFloat(CampusMapData.LATITUDE_COLUMN) * 1E6;
			        Double lng = campusLocations.getFloat(CampusMapData.LONGITUDE_COLUMN) * 1E6;
	
			        GeoPoint geoPoint = new GeoPoint(lat.intValue(), 
			                                         lng.intValue());
//			        String snippet = "P";
//		        	if (!lType.equalsIgnoreCase("P"))
				        //put the index of the location to snippet
		        		String snippet = Integer.toString(campusLocations.getInt(0));
		        		
		        		Drawable marker = null;
		        		
		        		if (lType.equalsIgnoreCase("S")) 
			        		marker = markers[campusLocations.getInt(CampusMapData.RINDEX_COLUMN)-1]; 
		        			
		        	addNewItem(geoPoint, campusLocations.getString(CampusMapData.NAME_COLUMN), snippet, marker);
		        
		      } while(campusLocations.moveToNext());
	}  
	
	
	/**
	 * Adds the new item.
	 *
	 * @param location the location
	 * @param markerText the marker text
	 * @param snippet the snippet
	 * @param marker the drawable marker
	 */
	public void addNewItem(GeoPoint location, String markerText,String snippet, Drawable marker) {
		OverlayItem newItem = new OverlayItem(location, markerText, snippet);
		if (marker!=null) {
//			boundCenter(marker);
			newItem.setMarker(marker);
		}
		items.add(newItem);
		//populate();
	}

	/**
	 * Removes the item.
	 *
	 * @param index the index
	 */
	public void removeItem(int index) {
		items.remove(index);
		populate();
	}
	
	/* (non-Javadoc)
	 * @see com.google.android.maps.ItemizedOverlay#createItem(int)
	 */
	@Override
	protected OverlayItem createItem(int index) {
		return items.get(index);
	}
	
	/* (non-Javadoc)
	 * @see com.google.android.maps.ItemizedOverlay#size()
	 */
	@Override
	public int size() {
		return items.size();
	}
	
	/* (non-Javadoc)
	 * @see com.google.android.maps.ItemizedOverlay#onTap(int)
	 */
	@Override
	/**
	 * When a location is tapped
	 * 	if it is a building, show its description, departments, and history
	 *  if it is a shuttle stop, show next bus arriving time on this stop
	 */
	protected boolean onTap(int index){
//		tappedIndex = index;
		String snippet;
		//remove old view
		boolean isRecycled;
		
		// declare a balloon popup view
		if (balloonView == null) {
			balloonView = new BalloonOverlayView(mapView.getContext(), viewOffset);
//			View clickRegion = (View) balloonView.findViewById(R.id.balloon_inner_layout);
			isRecycled = false;
		} else {
			isRecycled = true;
		}
	
		balloonView.setVisibility(View.GONE);

		List<Overlay> mapOverlays = mapView.getOverlays();
		if (mapOverlays.size() > 1) {
			hideOtherBalloons(mapOverlays);
		}

		OverlayItem tappedItem = items.get(index);
//		String _id = tappedItem.getSnippet();
//		campusLocations.moveToPosition(index);
		snippet = tappedItem.getTitle();
		if (lType.equalsIgnoreCase("V") || lType.equalsIgnoreCase("P")) return false;
		if (campusLocations.moveToPosition(index)){

			// if this is a shuttle stop
			int routeID = campusLocations.getInt(CampusMapData.RINDEX_COLUMN);
			if (routeID!=0){
				String busTime = Utils.nextBus(campusLocations.getString(CampusMapData.ROUTE_SHORT_COLUMN), campusLocations.getString(CampusMapData.DETAILS_COLUMN));
		          if (busTime!=null)
		        	  snippet = "Next bus for " + campusLocations.getString(CampusMapData.ROUTE_COLUMN)
		        	  	+ "\nwill arrive at " + campusLocations.getString(CampusMapData.NAME_COLUMN) + "\nin " + busTime + " minutes";
			}else{
				// if this is a building
				snippet = campusLocations.getString(CampusMapData.DETAILS_COLUMN);
				
				// add departments
				if (snippet==null) snippet ="";
				snippet +="Departments:";
				//find location id
				int locID = campusLocations.getInt(0);
				Uri departUri = Uri.parse("content://" + Constant.PKG + "/departments/" + locID);
				Cursor departCursor = mContext.getContentResolver().query(departUri,null, null, null, null);
				//read from database
				if (departCursor.moveToFirst())
				      do { 
				        		snippet += "\n" + departCursor.getString(CampusMapData.NAME_COLUMN);
				        
				      } while(departCursor.moveToNext());
				departCursor.close();
				// add history
				if (campusLocations.getString(CampusMapData.HISTORY_COLUMN)!=null)
					snippet += campusLocations.getString(CampusMapData.HISTORY_COLUMN);
//				snippet += "\n1\n3\n4\n5\n6\n6\n7\n8\n9\n0\n9\n-\n=\n9\n=\nk\n1\n3\n4\n5\n6\n6\n7\n8\n9\n0\n9\n-\n=\n9\n=\nk";
			}

			
			GeoPoint geoPoint =tappedItem.getPoint();
			MapView.LayoutParams params = new MapView.LayoutParams(
					LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, geoPoint,
					MapView.LayoutParams.BOTTOM_CENTER);
			params.mode = MapView.LayoutParams.MODE_MAP;
			
			balloonView.setData(tappedItem.getTitle(), snippet);
			balloonView.setVisibility(View.VISIBLE);

			if (isRecycled) {
				balloonView.setLayoutParams(params);
			} else {
				mapView.addView(balloonView, params);
			}
			
			//when the snippet is long
			if (snippet.length()> 300){
			//find the center point of the balloonView
			Projection projection = mapView.getProjection();
			Point point = new Point();
			projection.toPixels(geoPoint, point);

			//find the center point of the balloonView
//			int y = point.y - balloonView.getBHeight()/2;
			int y = point.y - mapView.getHeight()/2 + 80;
			int x = point.x;
			mc.animateTo(projection.fromPixels(x, y));
			}else{
				mc.animateTo(geoPoint);
				
			}

		}
		return true;
	}
	

	/* (non-Javadoc)
	 * @see com.google.android.maps.ItemizedOverlay#draw(android.graphics.Canvas, com.google.android.maps.MapView, boolean)
	 */
	/**
	 * draw marker of the location to the map
	 * Add name of the parking lot to the map
	 */
	@Override
    public void draw(android.graphics.Canvas canvas, MapView mapView, boolean shadow)
    {
        super.draw(canvas, mapView, shadow);
        
        // When zoom is close enough
        if ((shadow == false) && (mapView.getMaxZoomLevel() - mapView.getZoomLevel() < 5))
        {
            //cycle through all overlays
            for (int index = 0; index < items.size(); index++)
            {
                OverlayItem item = items.get(index);
                
                // Add name of the parking lot to the map
                if (lType.equalsIgnoreCase("P")){

	                // Converts lat/lng-Point to coordinates on the screen
	                GeoPoint point = item.getPoint();
	                Point ptScreenCoord = new Point() ;
	                mapView.getProjection().toPixels(point, ptScreenCoord);
	
	                //Paint text white with black border
	                Paint paint = new Paint();
	                paint.setTextAlign(Paint.Align.CENTER);
	                paint.setTextSize(mTextSize);
	    //            paint.setTypeface(Typeface.DEFAULT_BOLD);
	                paint.setStyle(Paint.Style.STROKE);
	                paint.setStrokeWidth(3);
	                paint.setARGB(200, 10, 10, 10);
	                paint.setShadowLayer(3, 0, 0, 0);
	                
	                //show text to the right of the icon
	                canvas.drawText(item.getTitle(), ptScreenCoord.x, ptScreenCoord.y+mTextSize, paint);
	                
	                paint.setStyle(Paint.Style.FILL);
	                paint.setARGB(250, 255, 255, 255);
	               // paint.setStrokeJoin(Paint.Join.BEVEL);
	                //show text to the right of the icon
	                canvas.drawText(item.getTitle(), ptScreenCoord.x, ptScreenCoord.y+mTextSize, paint);
                }
            }
        }
    }
	
    /**
     * Adds the overlay.
     *
     * @param overlay the overlay
     */
    public void addOverlay(OverlayItem overlay)
    {
        items.add(overlay);
        populate();
    }


    /**
     * Removes the overlay.
     *
     * @param overlay the overlay
     */
    public void removeOverlay(OverlayItem overlay)
    {
        items.remove(overlay);
        populate();
    }


    /**
     * Clear.
     */
    public void clear()
    {
        items.clear();
        populate();
    }

	/**
	 * Sets the visibility of this overlay's balloon view to GONE. 
	 */
	private void hideBalloon() {
		if (balloonView != null) {
			balloonView.setVisibility(View.GONE);
		}
	}
	
	/**
	 * Hides the balloon view for any other BalloonItemizedOverlay instances
	 * that might be present on the MapView.
	 * 
	 * @param overlays - list of overlays (including this) on the MapView.
	 */
	private void hideOtherBalloons(List<Overlay> overlays) {
		
		for (Overlay overlay : overlays) {
			if (overlay instanceof CampusMapOverlay && overlay != this) {
				((CampusMapOverlay) overlay).hideBalloon();
			}
		}
		
	}



	
}
